
import common
import re
from urllib.parse import quote, quote_plus # 将string转为url字符
import time
class Commit:
    def __init__(self, cve, mainline_commitId, stable_commitId, title, fixes_commitId, cve_url):
        self.cve = cve
        self.mainline_commitId = mainline_commitId
        self.stable_commitId = stable_commitId #5.10
        self.title = title
        self.fixes_commitId = fixes_commitId
        self.cve_url = cve_url
    def __str__(self):
        return "Commit('cve':{}, 'mainline_commitId':{}, 'stable_commitId':{}, 'title':{}, 'fixes_commitId':{}, 'cve_url':{})".format(self.cve, self.mainline_commitId, self.stable_commitId, self.title, self.fixes_commitId, self.cve_url)

#到linux的邮件列表中搜索cve 并返回其commitId(可能是mainline 也可能是stable，这里有一个优先级，stable > mainline)
def searchCVE(cve):
    if cve == "" or cve is None: 
        return []
    search_url = "https://lore.kernel.org/all/?q=" + quote(cve)
    soup = common.getSoup(search_url, __headers = None, __proxies = None)
    new_cve_list = [item for item in soup.find_all("a") if "New CVE" in item.text]
    return ["https://lore.kernel.org/all/"+item['href'] for item in new_cve_list]


def getCommitIdFromCVE(cve) :
    url_list = searchCVE(cve)
    if len(url_list) == 0:
        return None
    for url in url_list:
        resp_text = common.get(url, _headers = None, _proxies = None)
        all_match_text = re.search( r'{}(.|\n)*?(stable\/(.)*]\n)+'.format(cve), resp_text).group()
        # 可能出现没有mainline或者stable的情况
        mainline_match = re.search(r'mainline(.)*]\n', all_match_text)
        if mainline_match is None:
            mainline_commitId = None
        else:
            mainline_text = mainline_match.group()
            mainline_commitId = re.search(r'\[(.)*\]', mainline_text).group().strip('[]')
        stable_match = re.search(r'stable/5.10(.)*]\n', all_match_text)
        if stable_match is None:
            stable_commitId = None
        else:
            stable_text = stable_match.group()
            stable_commitId = re.search(r'\[(.)*\]', stable_text).group().strip('[]')
        stable_66_match = re.search(r'stable/6.6(.)*]\n', all_match_text)
        if stable_66_match is None:
            stable_66_commitId = None
        else:
            stable_66_text = stable_66_match.group()
            stable_66_commitId = re.search(r'\[(.)*\]', stable_66_text).group().strip('[]')
        # 从cve url中获取title
        title_match = re.search(r'{}: (.)*\n'.format(cve), all_match_text)
        if title_match is None:
            title = None
        else:
            title = title_match.group().strip().strip('{}: '.format(cve))
        # 从cve url中获取fixes commitId
        # fixes_match = re.search(r'Introduced(?: by | )commit(.)*\n(.)*', all_match_text)
        fixes_match_1 = re.search(r'Introduced commit(.)*\n(.)*', all_match_text)
        fixes_match_2 = re.search(r'Introduced by commit(.)*\n(.)*', all_match_text)
        if fixes_match_1 is None:
            if fixes_match_2 is None:
                fixes_commitId = None
            else:
                fixes_commitId = fixes_match_2.group().strip()
        else :
            fixes_commitId = fixes_match_1.group().strip()
        if fixes_commitId is not None:
            fixes_commitId = fixes_commitId.replace("\n", " ")
        return {'mainline': mainline_commitId, 'stable/5.10': stable_commitId,'stable/6.6': stable_66_commitId, 'url': url, 'title': title, 'fixes': fixes_commitId, 'all_match_text': all_match_text}